﻿namespace MSRI.SmsSessions
{
    using MSRI.HelperClasses;
    using System;
    using System.Collections.Generic;
    using System.Reflection;

    public class SmsMenuItem
    {
        private string _AltKey;
        private string _BackKey;
        private string _ErrorString;
        private string _footer;
        private string _header;
        private string _HomeKey;
        private List<SmsMenuItem> _Items;
        private string _key;
        private string _keyTextSeparator;
        private object _menuData;
        private int _moreCount;
        private string _MoreKey;
        private ResponseSessionStateEnum _ResponseSessionState;
        private string _responseString;
        private SmsSessionDelegate _SessionDelegate;
        private string _text;
        private MenuItemEnum _type;

        public SmsMenuItem()
        {
            this._text = "";
            this._key = null;
            this._AltKey = null;
            this._type = MenuItemEnum.CustomString;
            this._responseString = "";
            this._header = null;
            this._footer = null;
            this._menuData = null;
            this._moreCount = 0;
            this._MoreKey = null;
            this._BackKey = null;
            this._HomeKey = null;
            this._Items = null;
            this._ErrorString = "";
            this._ResponseSessionState = ResponseSessionStateEnum.Ignore;
            this._keyTextSeparator = "-";
        }

        public SmsMenuItem(SmsMenuItem Item)
        {
            this._text = Item.Text;
            this._key = Item.Key;
            this._AltKey = Item.AltKey;
            this._type = Item.Type;
            this._responseString = Item.ResponseString;
            this._header = Item.Header;
            this._footer = Item.Footer;
            this._menuData = null;
            this._moreCount = Item.MoreCount;
            this._MoreKey = Item.MoreKey;
            this._BackKey = Item.BackKey;
            this._HomeKey = Item.HomeKey;
            this._Items = Item.Items;
            this._ErrorString = Item.ErrorMessage;
            this._ResponseSessionState = Item.ResponseSessionState;
            this._keyTextSeparator = Item.KeyTextSeparator;
        }

        public SmsMenuItem(string MenuKey, string MenuText)
        {
            this._text = MenuText;
            this._key = MenuKey;
            this._AltKey = null;
            this._type = MenuItemEnum.CustomString;
            this._responseString = "";
            this._header = null;
            this._footer = null;
            this._menuData = null;
            this._moreCount = 0;
            this._MoreKey = null;
            this._BackKey = null;
            this._HomeKey = null;
            this._Items = null;
            this._ErrorString = "";
            this._ResponseSessionState = ResponseSessionStateEnum.Ignore;
            this._keyTextSeparator = "-";
        }

        public bool AddSubMenuItem(SmsMenuItem MenuItem)
        {
            if (this._Items == null)
            {
                this._Items = new List<SmsMenuItem>();
            }
            if (!this.ValidKey(MenuItem._key) || ((MenuItem._AltKey != null) && !this.ValidKey(MenuItem._AltKey)))
            {
                throw new Exception("Error: The Key or AltKey you are trying to register is already in use");
            }
            this._Items.Add(MenuItem);
            this._type = MenuItemEnum.NestedMenuItem;
            return true;
        }

        public void AttachCustomFuntion(SmsSessionDelegate FunctionName)
        {
            this._SessionDelegate = new SmsSessionDelegate(FunctionName.Invoke);
            this._type = MenuItemEnum.CustomFunction;
        }

        public SmsResponseClass CallCustomFunction(SmsClass SmsItem)
        {
            if (this._SessionDelegate != null)
            {
                return this._SessionDelegate(this._menuData, SmsItem);
            }
            return null;
        }

        public bool ClearSubMenuItems()
        {
            if (this._Items != null)
            {
                this._Items.Clear();
                this._moreCount = 0;
                return true;
            }
            return false;
        }

        private string GetString(int MaxLength, int start)
        {
            string str = "";
            MaxLength -= (this._footer == null) ? 0 : this._footer.Length;
            if (this._type == MenuItemEnum.CustomFunction)
            {
                return MenuItemEnum.CustomFunction.ToString();
            }
            if (this._type == MenuItemEnum.CustomString)
            {
                return MenuItemEnum.CustomString.ToString();
            }
            if (this._type != MenuItemEnum.NestedMenuItem)
            {
                return this._ErrorString;
            }
            int num = start;
            str = (this._header == null) ? "" : (this._header + Environment.NewLine);
            string str2 = (this._MoreKey == null) ? "" : string.Format("{0}{1}More\n", this._MoreKey, this._keyTextSeparator);
            for (num = start; (num < this._Items.Count) && (str.Length < MaxLength); num++)
            {
                string str3 = string.Format("{0}{2}{1}\n", this._Items[num]._key, this._Items[num]._text, this._keyTextSeparator);
                if (num == (this._Items.Count - 1))
                {
                    if ((str.Length + str3.Length) > MaxLength)
                    {
                        this._moreCount = num;
                        str = str + str2;
                        break;
                    }
                    this._moreCount = num + 1;
                    str = str + str3;
                }
                else
                {
                    if (((str.Length + str3.Length) + str2.Length) > MaxLength)
                    {
                        this._moreCount = num;
                        str = str + str2;
                        break;
                    }
                    str = str + str3;
                }
            }
            return (str + ((this._footer == null) ? "" : this._footer));
        }

        public string More(int MaxLength)
        {
            if ((this._Items != null) && (this._moreCount != this._Items.Count))
            {
                return this.GetString(MaxLength, this._moreCount);
            }
            return this._ErrorString;
        }

        public string ToString(int MaxLength)
        {
            return this.GetString(MaxLength, 0);
        }

        private bool ValidKey(string CheckKey)
        {
            if (((CheckKey == null) || (CheckKey.Trim().Length == 0)) || (((CheckKey.Trim() == this._MoreKey) || (CheckKey.Trim() == this._BackKey)) || (CheckKey.Trim() == this._HomeKey)))
            {
                return false;
            }
            if ((this._type == MenuItemEnum.NestedMenuItem) && (this._Items == null))
            {
                for (int i = 0; i < this._Items.Count; i++)
                {
                    if ((this._Items[i].Key == CheckKey.Trim()) || (this._Items[i].AltKey == CheckKey.Trim()))
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        public string AltKey
        {
            get
            {
                return this._AltKey;
            }
            set
            {
                this._AltKey = value;
            }
        }

        public string BackKey
        {
            get
            {
                return this._BackKey;
            }
            set
            {
                if ((value != null) && !this.ValidKey(value))
                {
                    throw new Exception("Error:Invalid Menu Key or Key already in use");
                }
                this._BackKey = value;
            }
        }

        public string ErrorMessage
        {
            get
            {
                return this._ErrorString;
            }
            set
            {
                this._ErrorString = value;
            }
        }

        public string Footer
        {
            get
            {
                return this._footer;
            }
            set
            {
                this._footer = value;
            }
        }

        public string Header
        {
            get
            {
                return this._header;
            }
            set
            {
                this._header = value;
            }
        }

        public string HomeKey
        {
            get
            {
                return this._HomeKey;
            }
            set
            {
                if ((value != null) && !this.ValidKey(value))
                {
                    throw new Exception("Error:Invalid Menu Key or Key already in use");
                }
                this._HomeKey = value;
            }
        }

        public SmsMenuItem this[string MenuKey]
        {
            get
            {
                if (((this._Items != null) && (MenuKey != null)) && (MenuKey.Trim().Length != 0))
                {
                    for (int i = 0; i < this._Items.Count; i++)
                    {
                        if ((this._Items[i]._key == MenuKey) || (this._Items[i]._AltKey == MenuKey))
                        {
                            return this._Items[i];
                        }
                    }
                }
                return null;
            }
        }

        public List<SmsMenuItem> Items
        {
            get
            {
                return this._Items;
            }
        }

        public string Key
        {
            get
            {
                return this._key;
            }
            set
            {
                if (value != null)
                {
                    this._key = value.Trim();
                }
                else
                {
                    this._key = "";
                }
            }
        }

        public string KeyTextSeparator
        {
            get
            {
                return this._keyTextSeparator;
            }
            set
            {
                this._keyTextSeparator = value;
            }
        }

        public object MenuData
        {
            get
            {
                return this._menuData;
            }
            set
            {
                this._menuData = value;
            }
        }

        public int MoreCount
        {
            get
            {
                return this._moreCount;
            }
        }

        public string MoreKey
        {
            get
            {
                return this._MoreKey;
            }
            set
            {
                if ((value != null) && !this.ValidKey(value))
                {
                    throw new Exception("Error:Invalid Menu Key or Key already in use");
                }
                this._MoreKey = value;
            }
        }

        public ResponseSessionStateEnum ResponseSessionState
        {
            get
            {
                return this._ResponseSessionState;
            }
            set
            {
                this._ResponseSessionState = value;
            }
        }

        public string ResponseString
        {
            get
            {
                return this._responseString;
            }
            set
            {
                if (this._responseString != null)
                {
                    this._type = MenuItemEnum.CustomString;
                    this._responseString = value;
                }
                else
                {
                    this._responseString = null;
                }
            }
        }

        public SmsSessionDelegate SessionDelegate
        {
            get
            {
                return this._SessionDelegate;
            }
        }

        public string Text
        {
            get
            {
                return this._text;
            }
            set
            {
                this._text = value;
            }
        }

        public MenuItemEnum Type
        {
            get
            {
                return this._type;
            }
            set
            {
                this._type = value;
            }
        }
    }
}

